---
title: Updates
description: A library that enables your app to manage remote updates to your application code.
sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-updates'
packageName: 'expo-updates'
iconUrl: '/static/images/packages/expo-updates.png'
platforms: ['android', 'ios', 'tvos']
---

import { GithubIcon } from '@expo/styleguide-icons/custom/GithubIcon';

import APISection from '~/components/plugins/APISection';
import { APIInstallSection } from '~/components/plugins/InstallSection';
import { BoxLink } from '~/ui/components/BoxLink';
import { Collapsible } from '~/ui/components/Collapsible';
import { YesIcon, NoIcon } from '~/ui/components/DocIcons';

`expo-updates` is a library that enables your app to manage remote updates to your application code. It communicates with the configured remote update service to get information about available updates.

## Installation and configuration

The `expo-updates` library can be automatically configured using [EAS Update](/eas-update/introduction/), which is a hosted service that manages and serves updates to your app. To get started with EAS Update, follow the instructions in the [Get started](/eas-update/getting-started/) guide.

Alternatively, it is also possible to configure the `expo-updates` library manually in cases where a different remote update service is required or configuration is only specified in native files.

<Collapsible summary="Manual installation, configuration, and custom remote update services">

<APIInstallSection hideBareInstructions />

If you're installing this library in a [bare React Native app](/bare/overview/) or a generic app with manually configured native code, follow these [installation instructions](/bare/installing-updates/).

If using [app config](/workflow/configuration/) for configuration, this library can be configured by setting at least the following app config properties:

- [`updates.url`](/versions/latest/config/app/#updates): a URL of a remote service implementing the [Expo Updates protocol](/technical-specs/expo-updates-1/)
- [`runtimeVersion`](/versions/latest/config/app/#runtimeversion): a [runtime version](/eas-update/runtime-versions/)

The remote service must implement the [Expo Updates protocol](/technical-specs/expo-updates-1/). [EAS Update](/eas-update/introduction) is one such service, but it is also possible to use this library with a custom server.

<BoxLink
  title="Custom Expo Updates Server"
  description="Example implementation of a custom server and an app using that server"
  href="https://github.com/expo/custom-expo-updates-server"
  Icon={GithubIcon}
/>

</Collapsible>

### Additional configuration options

These are build-time configuration options that control the behavior of the library. For most apps, these configuration values can be set in the [app config](/workflow/configuration/) under the [`updates` property](/versions/latest/config/app/#updates).

You can also configure the library in your app's native project files if your project does not use Continuous Native Generation. It is also possible to override the configuration from native code.

<Collapsible summary="Native configuration instructions">

On Android, these options are set as `meta-data` tags in the **AndroidManifest.xml** file (adjacent to the tags added during installation if auto-setup was used). You can also set or override them at runtime using `UpdatesController.overrideConfiguration()`.

On iOS, these properties are set as keys in the **Expo.plist** file. You can also set or override them at runtime by calling `AppController.overrideConfiguration`.

<Collapsible summary="Importing Swift generated headers for use in Objective-C++">

If your iOS native code or `AppDelegate.mm` is written in Objective-C++, you will need to add the following imports to reference methods on `EXUpdatesAppController`. This is only necessary for overriding configuration at runtime.

```objc
#import "ExpoModulesCore-Swift.h"
#import "EXUpdatesInterface-Swift.h"
#import "EXUpdates-Swift.h"
```

</Collapsible>

</Collapsible>

| [App Config property](/versions/latest/config/app/#updates) | Default  | Required?   | iOS plist/dictionary key          | Android meta-data name                                           | Android Map key          |
| ----------------------------------------------------------- | -------- | ----------- | --------------------------------- | ---------------------------------------------------------------- | ------------------------ |
| `updates.enabled`                                           | `true`   | <NoIcon />  | `EXUpdatesEnabled`                | `expo.modules.updates.ENABLED`                                   | `enabled`                |
| `updates.url`                                               | (none)   | <YesIcon /> | `EXUpdatesURL`                    | `expo.modules.updates.EXPO_UPDATE_URL`                           | `updateUrl`              |
| `updates.requestHeaders`                                    | (none)   | <NoIcon />  | `EXUpdatesRequestHeaders`         | `expo.modules.updates.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY` | `requestHeaders`         |
| `runtimeVersion`                                            | (none)   | <YesIcon /> | `EXUpdatesRuntimeVersion`         | `expo.modules.updates.EXPO_RUNTIME_VERSION`                      | `runtimeVersion`         |
| `updates.checkAutomatically`                                | `ALWAYS` | <NoIcon />  | `EXUpdatesCheckOnLaunch`          | `expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH`              | `checkOnLaunch`          |
| `updates.fallbackToCacheTimeout`                            | `0`      | <NoIcon />  | `EXUpdatesLaunchWaitMs`           | `expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS`               | `launchWaitMs`           |
| `updates.codeSigningCertificate`                            | (none)   | <NoIcon />  | `EXUpdatesCodeSigningCertificate` | `expo.modules.updates.CODE_SIGNING_CERTIFICATE`                  | `codeSigningCertificate` |
| `updates.codeSigningMetadata`                               | (none)   | <NoIcon />  | `EXUpdatesCodeSigningMetadata`    | `expo.modules.updates.CODE_SIGNING_METADATA`                     | `codeSigningMetadata`    |

## Usage

By default, `expo-updates` checks for updates when the app launches. If an update is available, it downloads the update and applies it the next time the app is restarted. You can tune this startup behavior using the `checkAutomatically` and `fallbackToCacheTimeout` configuration options above.

The library also provides a variety of constants to inspect the current update and functions to customize update behavior from your application code (after startup). For example, one common alternative usage pattern is to manually check for updates after the app has started instead of doing the default check on launch.

<Collapsible summary="Example: Check for updates manually">

You can configure your app to check for updates manually by doing the following steps:

1. Set the `checkAutomatically` configuration value to `ON_ERROR_RECOVERY` or `NEVER` to disable the library's default launch behavior.
2. Add the following code to check for available updates, download them, and reload:

   ```jsx App.js
   import { View, Button } from 'react-native';
   import * as Updates from 'expo-updates';

   function App() {
     async function onFetchUpdateAsync() {
       try {
         const update = await Updates.checkForUpdateAsync();

         if (update.isAvailable) {
           await Updates.fetchUpdateAsync();
           await Updates.reloadAsync();
         }
       } catch (error) {
         // You can also add an alert() to see the error message in case of an error when fetching updates.
         alert(`Error fetching latest Expo update: ${error}`);
       }
     }

     return (
       <View>
         <Button title="Fetch update" onPress={onFetchUpdateAsync} />
       </View>
     );
   }
   ```

</Collapsible>

## Testing

Most of the methods and constants in this library can be used or tested only in release builds. In debug builds, the default behavior is to always load the latest JavaScript from a development server. It is possible to [build a debug version of your app with the same updates behavior as a release build](/eas-update/debug-advanced/#debugging-of-native-code-while-loading-the-app-through-expo-updates). Such an app will not open the latest JavaScript from your development server &mdash; it will load published updates just as a release build does. This may be useful for debugging the behavior of your app when it is not connected to a development server.

**To test the content of an update in a development build**, run [`eas update`](/eas-update/publish/) and then browse to the update in your development build. Note that this only simulates what an update will look like in your app, and most of the [Updates API](#api) is unavailable when running in a development build.

**To test updates in a release build**, you can create a [**.apk**](/build-reference/apk) or a [simulator build](/build-reference/simulators), or make a release build locally with `npx expo run:android --variant release` and `npx expo run:ios --configuration Release` (you don't need to submit this build to the store to test). The full [Updates API](#api) is available in a release build.

**To test the content of an update in Expo Go**, run [`eas update`](/eas-update/publish/) and then browse to the update in Expo Go. Note that this only simulates what an update will look like in your app, and most of the [Updates API](#api) is unavailable when running in Expo Go. Also note that only updates using [Expo Go-compatible libraries](/workflow/using-libraries/#determining-third-party-library-compatibility) are supported.

## API

```js
import * as Updates from 'expo-updates';
```

<APISection packageName="expo-updates" apiName="Updates" />

## Error codes

| Code                              | Description                                                                                                                                                                                                                                                    |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ERR_UPDATES_DISABLED`            | A method call was attempted when the Updates library was disabled, or the application was running in development mode                                                                                                                                          |
| `ERR_UPDATES_RELOAD`              | An error occurred when trying to reload the application and it could not be reloaded. For bare workflow apps, double check the setup steps for this library to ensure it has been installed correctly and the proper native initialization methods are called. |
| `ERR_UPDATES_CHECK`               | An unexpected error occurred when trying to check for new updates. Check the error message for more information.                                                                                                                                               |
| `ERR_UPDATES_FETCH`               | An unexpected error occurred when trying to fetch a new update. Check the error message for more information.                                                                                                                                                  |
| `ERR_UPDATES_READ_LOGS`           | An unexpected error occurred when trying to read log entries. Check the error message for more information.                                                                                                                                                    |
| `ERR_NOT_AVAILABLE_IN_DEV_CLIENT` | A method is not available when running in a development build. A release build should be used to test this method.                                                                                                                                             |
